#if !defined(FAKE_D3D11_DEVICE_H)
#define FAKE_D3D11_DEVICE_H

#include <d3d11.h>
#include <rt/Exceptions/NotImplementedException.h>

class FakeD3D11Device : public ID3D11Device
{
public:
	FakeD3D11Device()
		: CreateBlendStateCalled(false), CreateBlendStateLastDesc(0), CreateBlendStateFakeResult(0), CreateBlendStateFakeHResult(E_FAIL),
		CreateRasterizerStateCalled(false), CreateRasterizerStateLastDesc(0), CreateRasterizerStateFakeResult(0), CreateRasterizerStateFakeHResult(E_FAIL),
		CreateDepthStencilStateCalled(false), CreateDepthStencilStateLastDesc(0), CreateDepthStencilStateFakeResult(0), CreateDepthStencilStateFakeHResult(E_FAIL),
		CreateQueryCalled(false), CreateQueryLastDesc(0), CreateQueryFakeResult(0), CreateQueryFakeHResult(E_FAIL),
		CreateCounterCalled(false), CreateCounterLastDesc(0), CreateCounterFakeResult(0), CreateCounterFakeHResult(E_FAIL),
		CreateDepthStencilViewCalled(false), CreateDepthStencilViewLastResource(0), CreateDepthStencilViewLastDesc(0), CreateDepthStencilViewFakeResult(0), CreateDepthStencilViewFakeHResult(E_FAIL),
		CreatePredicateCalled(false), CreatePredicateLastDesc(0), CreatePredicateFakeResult(0), CreatePredicateFakeHResult(E_FAIL),
		CreateRenderTargetViewCalled(false), CreateRenderTargetViewLastResource(0), CreateRenderTargetViewLastDesc(0), CreateRenderTargetViewFakeResult(0), CreateRenderTargetViewFakeHResult(E_FAIL),
		CreateSamplerStateCalled(false), CreateSamplerStateLastDesc(0), CreateSamplerStateFakeResult(0), CreateSamplerStateFakeHResult(E_FAIL),
		CreateShaderResourceViewCalled(false), CreateShaderResourceViewLastResource(0), CreateShaderResourceViewLastDesc(0), CreateShaderResourceViewFakeResult(0), CreateShaderResourceViewFakeHResult(E_FAIL),
		CreateBufferCalled(false), CreateBufferLastData(0), CreateBufferLastDesc(0), CreateBufferFakeResult(0), CreateBufferFakeHResult(E_FAIL),
		CreateTexture1DCalled(false), CreateTexture1DLastData(0), CreateTexture1DLastDesc(0), CreateTexture1DFakeResult(0), CreateTexture1DFakeHResult(E_FAIL),
		CreateTexture2DCalled(false), CreateTexture2DLastData(0), CreateTexture2DLastDesc(0), CreateTexture2DFakeResult(0), CreateTexture2DFakeHResult(E_FAIL),
		CreateTexture3DCalled(false), CreateTexture3DLastData(0), CreateTexture3DLastDesc(0), CreateTexture3DFakeResult(0), CreateTexture3DFakeHResult(E_FAIL),
		CreateUnorderedAccessViewCalled(false), CreateUnorderedAccessViewLastResource(0), CreateUnorderedAccessViewLastDesc(0), CreateUnorderedAccessViewFakeResult(0), CreateUnorderedAccessViewFakeHResult(E_FAIL)
	{
	}
	bool CreateBlendStateCalled;
	D3D11_BLEND_DESC const *CreateBlendStateLastDesc;
	ID3D11BlendState *CreateBlendStateFakeResult;
	HRESULT CreateBlendStateFakeHResult;
	bool CreateRasterizerStateCalled;
	D3D11_RASTERIZER_DESC const *CreateRasterizerStateLastDesc;
	ID3D11RasterizerState *CreateRasterizerStateFakeResult;
	HRESULT CreateRasterizerStateFakeHResult;
	bool CreateDepthStencilStateCalled;
	D3D11_DEPTH_STENCIL_DESC const *CreateDepthStencilStateLastDesc;
	ID3D11DepthStencilState *CreateDepthStencilStateFakeResult;
	HRESULT CreateDepthStencilStateFakeHResult;
	bool CreateQueryCalled;
	D3D11_QUERY_DESC const *CreateQueryLastDesc;
	ID3D11Query *CreateQueryFakeResult;
	HRESULT CreateQueryFakeHResult;
	bool CreateCounterCalled;
	D3D11_COUNTER_DESC const *CreateCounterLastDesc;
	ID3D11Counter *CreateCounterFakeResult;
	HRESULT CreateCounterFakeHResult;
	bool CreateDepthStencilViewCalled;
	ID3D11Resource *CreateDepthStencilViewLastResource;
	D3D11_DEPTH_STENCIL_VIEW_DESC const *CreateDepthStencilViewLastDesc;
	ID3D11DepthStencilView *CreateDepthStencilViewFakeResult;
	HRESULT CreateDepthStencilViewFakeHResult;
	bool CreatePredicateCalled;
	D3D11_QUERY_DESC const *CreatePredicateLastDesc;
	ID3D11Predicate *CreatePredicateFakeResult;
	HRESULT CreatePredicateFakeHResult;
	bool CreateRenderTargetViewCalled;
	ID3D11Resource *CreateRenderTargetViewLastResource;
	D3D11_RENDER_TARGET_VIEW_DESC const *CreateRenderTargetViewLastDesc;
	ID3D11RenderTargetView *CreateRenderTargetViewFakeResult;
	HRESULT CreateRenderTargetViewFakeHResult;
	bool CreateSamplerStateCalled;
	D3D11_SAMPLER_DESC const *CreateSamplerStateLastDesc;
	ID3D11SamplerState *CreateSamplerStateFakeResult;
	HRESULT CreateSamplerStateFakeHResult;
	bool CreateShaderResourceViewCalled;
	ID3D11Resource *CreateShaderResourceViewLastResource;
	D3D11_SHADER_RESOURCE_VIEW_DESC const *CreateShaderResourceViewLastDesc;
	ID3D11ShaderResourceView *CreateShaderResourceViewFakeResult;
	HRESULT CreateShaderResourceViewFakeHResult;
	bool CreateBufferCalled;
	D3D11_BUFFER_DESC const *CreateBufferLastDesc;
	D3D11_SUBRESOURCE_DATA const *CreateBufferLastData;
	ID3D11Buffer *CreateBufferFakeResult;
	HRESULT CreateBufferFakeHResult;
	bool CreateTexture1DCalled;
	D3D11_TEXTURE1D_DESC const *CreateTexture1DLastDesc;
	D3D11_SUBRESOURCE_DATA const *CreateTexture1DLastData;
	ID3D11Texture1D *CreateTexture1DFakeResult;
	HRESULT CreateTexture1DFakeHResult;
	bool CreateTexture2DCalled;
	D3D11_TEXTURE2D_DESC const *CreateTexture2DLastDesc;
	D3D11_SUBRESOURCE_DATA const *CreateTexture2DLastData;
	ID3D11Texture2D *CreateTexture2DFakeResult;
	HRESULT CreateTexture2DFakeHResult;
	bool CreateTexture3DCalled;
	D3D11_TEXTURE3D_DESC const *CreateTexture3DLastDesc;
	D3D11_SUBRESOURCE_DATA const *CreateTexture3DLastData;
	ID3D11Texture3D *CreateTexture3DFakeResult;
	HRESULT CreateTexture3DFakeHResult;
	bool CreateUnorderedAccessViewCalled;
	ID3D11Resource *CreateUnorderedAccessViewLastResource;
	D3D11_UNORDERED_ACCESS_VIEW_DESC const *CreateUnorderedAccessViewLastDesc;
	ID3D11UnorderedAccessView *CreateUnorderedAccessViewFakeResult;
	HRESULT CreateUnorderedAccessViewFakeHResult;

	// IUnknown
	virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { throw rt::NotImplementedException(); }
	virtual ULONG STDMETHODCALLTYPE AddRef()	{ throw rt::NotImplementedException(); }
	virtual ULONG STDMETHODCALLTYPE Release()	{ throw rt::NotImplementedException(); }

	// ID3D11Device
	virtual HRESULT STDMETHODCALLTYPE CreateBuffer(const D3D11_BUFFER_DESC *pDesc, const D3D11_SUBRESOURCE_DATA *pInitialData, ID3D11Buffer **ppBuffer)
	{
		CreateBufferCalled = true;
		CreateBufferLastDesc = pDesc;
		CreateBufferLastData = pInitialData;
		*ppBuffer = CreateBufferFakeResult;
		return CreateBufferFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateTexture1D(const D3D11_TEXTURE1D_DESC *pDesc, const D3D11_SUBRESOURCE_DATA *pInitialData, ID3D11Texture1D **ppTexture1D)
	{
		CreateTexture1DCalled = true;
		CreateTexture1DLastDesc = pDesc;
		CreateTexture1DLastData = pInitialData;
		*ppTexture1D = CreateTexture1DFakeResult;
		return CreateTexture1DFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateTexture2D(const D3D11_TEXTURE2D_DESC *pDesc, const D3D11_SUBRESOURCE_DATA *pInitialData, ID3D11Texture2D **ppTexture2D)
	{
		CreateTexture2DCalled = true;
		CreateTexture2DLastDesc = pDesc;
		CreateTexture2DLastData = pInitialData;
		*ppTexture2D = CreateTexture2DFakeResult;
		return CreateTexture2DFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateTexture3D(const D3D11_TEXTURE3D_DESC *pDesc, const D3D11_SUBRESOURCE_DATA *pInitialData, ID3D11Texture3D **ppTexture3D)
	{
		CreateTexture3DCalled = true;
		CreateTexture3DLastDesc = pDesc;
		CreateTexture3DLastData = pInitialData;
		*ppTexture3D = CreateTexture3DFakeResult;
		return CreateTexture3DFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView(ID3D11Resource *pResource, const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, ID3D11ShaderResourceView **ppSRView)
	{
		CreateShaderResourceViewCalled = true;
		CreateShaderResourceViewLastResource = pResource;
		CreateShaderResourceViewLastDesc = pDesc;
		*ppSRView = CreateShaderResourceViewFakeResult;
		return CreateShaderResourceViewFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView(ID3D11Resource *pResource, const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, ID3D11UnorderedAccessView **ppUAView)
	{
		CreateUnorderedAccessViewCalled = true;
		CreateUnorderedAccessViewLastResource = pResource;
		CreateUnorderedAccessViewLastDesc = pDesc;
		*ppUAView = CreateUnorderedAccessViewFakeResult;
		return CreateUnorderedAccessViewFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateRenderTargetView(ID3D11Resource *pResource, const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, ID3D11RenderTargetView **ppRTView)
	{
		CreateRenderTargetViewCalled = true;
		CreateRenderTargetViewLastResource = pResource;
		CreateRenderTargetViewLastDesc = pDesc;
		*ppRTView = CreateRenderTargetViewFakeResult;
		return CreateRenderTargetViewFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilView(ID3D11Resource *pResource, const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, ID3D11DepthStencilView **ppDepthStencilView)
	{
		CreateDepthStencilViewCalled = true;
		CreateDepthStencilViewLastResource = pResource;
		CreateDepthStencilViewLastDesc = pDesc;
		*ppDepthStencilView = CreateDepthStencilViewFakeResult;
		return CreateDepthStencilViewFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, UINT NumElements, const void *pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength, ID3D11InputLayout **ppInputLayout) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreateVertexShader(const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11VertexShader **ppVertexShader) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreateGeometryShader(const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11GeometryShader **ppGeometryShader) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput(const void *pShaderBytecode, SIZE_T BytecodeLength, const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT NumEntries, const UINT *pBufferStrides, UINT NumStrides, UINT RasterizedStream, ID3D11ClassLinkage *pClassLinkage, ID3D11GeometryShader **ppGeometryShader) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreatePixelShader(const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11PixelShader **ppPixelShader) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreateHullShader(const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11HullShader **ppHullShader) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreateDomainShader(const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11DomainShader **ppDomainShader) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreateComputeShader(const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11ComputeShader **ppComputeShader) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreateClassLinkage(ID3D11ClassLinkage **ppLinkage) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CreateBlendState(const D3D11_BLEND_DESC *pBlendStateDesc, ID3D11BlendState **ppBlendState)
	{
		CreateBlendStateCalled = true;
		CreateBlendStateLastDesc = pBlendStateDesc;
		*ppBlendState = CreateBlendStateFakeResult;
		return CreateBlendStateFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilState(const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, ID3D11DepthStencilState **ppDepthStencilState)
	{
		CreateDepthStencilStateCalled = true;
		CreateDepthStencilStateLastDesc = pDepthStencilDesc;
		*ppDepthStencilState = CreateDepthStencilStateFakeResult;
		return CreateDepthStencilStateFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateRasterizerState(const D3D11_RASTERIZER_DESC *pRasterizerDesc, ID3D11RasterizerState **ppRasterizerState)
	{
		CreateRasterizerStateCalled = true;
		CreateRasterizerStateLastDesc = pRasterizerDesc;
		*ppRasterizerState = CreateRasterizerStateFakeResult;
		return CreateRasterizerStateFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateSamplerState(const D3D11_SAMPLER_DESC *pSamplerDesc, ID3D11SamplerState **ppSamplerState)
	{
		CreateSamplerStateCalled = true;
		CreateSamplerStateLastDesc = pSamplerDesc;
		*ppSamplerState = CreateSamplerStateFakeResult;
		return CreateSamplerStateFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateQuery(const D3D11_QUERY_DESC *pQueryDesc, ID3D11Query **ppQuery)
	{
		CreateQueryCalled = true;
		CreateQueryLastDesc = pQueryDesc;
		*ppQuery = CreateQueryFakeResult;
		return CreateQueryFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreatePredicate(const D3D11_QUERY_DESC *pPredicateDesc, ID3D11Predicate **ppPredicate)
	{
		CreatePredicateCalled = true;
		CreatePredicateLastDesc = pPredicateDesc;
		*ppPredicate = CreatePredicateFakeResult;
		return CreatePredicateFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateCounter(const D3D11_COUNTER_DESC *pCounterDesc, ID3D11Counter **ppCounter)
	{
		CreateCounterCalled = true;
		CreateCounterLastDesc = pCounterDesc;
		*ppCounter = CreateCounterFakeResult;
		return CreateCounterFakeHResult;
	}
	virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext(UINT ContextFlags, ID3D11DeviceContext **ppDeferredContext) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE OpenSharedResource(HANDLE hResource, REFIID ReturnedInterface, void **ppResource) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CheckFormatSupport(DXGI_FORMAT Format, UINT *pFormatSupport) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels(DXGI_FORMAT Format, UINT SampleCount, UINT *pNumQualityLevels) { throw rt::NotImplementedException(); }
	virtual void STDMETHODCALLTYPE CheckCounterInfo(D3D11_COUNTER_INFO *pCounterInfo) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CheckCounter(const D3D11_COUNTER_DESC *pDesc, D3D11_COUNTER_TYPE *pType, UINT *pActiveCounters, LPSTR szName, UINT *pNameLength, LPSTR szUnits, UINT *pUnitsLength, LPSTR szDescription, UINT *pDescriptionLength) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE CheckFeatureSupport(D3D11_FEATURE Feature, void *pFeatureSupportData, UINT FeatureSupportDataSize) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid, UINT DataSize, const void *pData) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID guid, const IUnknown *pData) { throw rt::NotImplementedException(); }
	virtual D3D_FEATURE_LEVEL STDMETHODCALLTYPE GetFeatureLevel() { throw rt::NotImplementedException(); }
	virtual UINT STDMETHODCALLTYPE GetCreationFlags() { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason() { throw rt::NotImplementedException(); }
	virtual void STDMETHODCALLTYPE GetImmediateContext(ID3D11DeviceContext **ppImmediateContext) { throw rt::NotImplementedException(); }
	virtual HRESULT STDMETHODCALLTYPE SetExceptionMode(UINT RaiseFlags) { throw rt::NotImplementedException(); }
	virtual UINT STDMETHODCALLTYPE GetExceptionMode() { throw rt::NotImplementedException(); }
};

#endif
